'''
An RPG Modification for Source games using Source Python.

    Copyright (C) 2012 Steven Hartin

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.

Created on 28 Dec 2012

@author: Steven Hartin
@file: ../sourcerpg/plugin/commands.py
'''

from commands.client import ClientCommand
from commands.say import SayCommand
from commands.server import ServerCommand
from entities.helpers import index_from_edict, edict_from_index
from players.helpers import userid_from_edict

from sourcerpg.utils.baseclass import BaseClass
from sourcerpg.player import players
from sourcerpg.popups import UpgradePopup, DowngradePopup


__all__ = ["ClientCommands", "ServerCommands"]


class ClientCommands(BaseClass):
    """Class to store / respond to client commands (not server)"""
    class ClientSayCommand(object):
        """Class to use both client and say commands for the same callback"""
        def __init__(self, *args, **kwargs):
            """Create our client / say command instances"""
            self.client_command = ClientCommand(*args, **kwargs)
            self.say_command = SayCommand(*args, **kwargs)

        def __call__(self, callback):
            """Hook the call method to simulate the decorator functionality"""
            def say_command_callback(index, teamonly, CCommand):
                # Say commands have command as first arg
                args = CCommand.ArgS()
                args = " ".join(args.split()[1:])
                argc = CCommand.ArgC() - 1
                callback(edict_from_index(index), argc, args)

            def client_command_callback(edict, CCommand):
                callback(edict, CCommand.ArgC(), CCommand.ArgS())

            self.client_command.__call__(client_command_callback)
            self.say_command.__call__(say_command_callback)

    @staticmethod
    @ClientSayCommand("rpgupgrade")
    def rpgupgrade(edict, argc, args):
        """Upgrade a player's skill, or send them a popup to decide

        Syntax:
            rpgupgrade [skill_name]

        If skil_name is left blank, send a popup. Otherwise, attempt
        to upgrade the skill they passed in.

        """
        if (argc <= 1):
            # No commands, send the menu
            ent_index = index_from_edict(edict)
            userid = userid_from_edict(edict)
            menu = UpgradePopup(players[userid])
            menu.add_skills()
            menu.send(ent_index)
        else:
            # Assume the skil name is in the first parameter
            skill_name = args.split()[0].lower()
            userid = userid_from_edict(edict)
            player = players[userid]
            if player.upgrade_skill(skill_name) is True:
                player.send_message("%s Successfully upgraded" % skill_name)
        return True

    @staticmethod
    @ClientSayCommand("rpgsell")
    def rpgsell(edict, argc, args):
        """Sells a player's skill, or sends them to a popup to decide

        Syntax:
            rpgsell [skill_name]

        If skil_name is left blank, send a popup. Otherwise, attempt
        to sell the skill they passed in.

        """
        if (argc <= 1):
            # No commands, send the menu
            ent_index = index_from_edict(edict)
            userid = userid_from_edict(edict)
            menu = DowngradePopup(players[userid])
            menu.add_skills()
            menu.send(ent_index)
        else:
            # Assume the skil name is in the first parameter
            skill_name = args.split()[0].lower()
            userid = userid_from_edict(edict)
            player = players[userid]
            if player.downgrade_skill(skill_name) is True:
                player.send_message("%s Successfully sold" % skill_name)
        return True


class ServerCommands(BaseClass):
    """Class to store / respond to server commands (not client)"""
    pass
